package com.way.fileexplorer.activities;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

import com.way.fileexplorer.StorageReceiver;
import com.way.fileexplorer.adapters.FileListAdapter;
import com.way.fileexplorer.fragments.BaseFragment;
import com.way.fileexplorer.fragments.DetailedListFragment;
import com.way.fileexplorer.fragments.OverViewFragment;
import com.way.fileexplorer.util.IStorageUtil.StorageChangedListener;
import com.way.fileexplorer.util.StorageUtil;
import com.way.fileexplorer.R;

public class FileExploreActivity extends FragmentActivity {

	private static final String TAG = "FileExploreActivity";

	private SparseArray<StorageStatus> mStorageStatus = new SparseArray<StorageStatus>();
	private static final int STORAGE_SYZE = 3;
	private BaseFragment mCurrentFragment;
	private ActionBar mActionBar;
	private ArrayAdapter<String> mNavigationAdapter;
	/**
	 * The {@link android.support.v4.view.PagerAdapter} that will provide
	 * fragments for each of the sections. We use a
	 * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
	 * will keep every loaded fragment in memory. If this becomes too memory
	 * intensive, it may be best to switch to a
	 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
	 */
	private SectionsPagerAdapter mPagerAdapter;
	/**
	 * The {@link ViewPager} that will host the section contents.
	 */
	private ViewPager mViewPager;

    StorageChangedListener mStorageChangedListener = new StorageChangedListener() {

        @Override
        public void onStorageChanged(final String path, final boolean available) {
            Log.d(TAG, "StorageChanged: path = " + path + " available = " + available);
            new Handler(getMainLooper()).post(new Runnable() {

                @Override
                public void run() {
                    FileExploreActivity.this.onStorageChanged(path, available);
                }
            });
        }
    };

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Exception occurred from support framework, make a workaround
        // currently and have two choices in future:
        // 1. Give up FragmentActivity, using Activity instead.
        // 2. Learn more about FragmentActivity, FragmentManager and
        // FragmentState.
	    Log.i(TAG, "start onCreate");
        super.onCreate(null);
        setContentView(R.layout.activity_file_explore);
        StorageUtil.addStorageChangeListener(mStorageChangedListener);
		init();
		Log.i(TAG, "end onCreate");
	}

    private void init() {
        mPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        mCurrentFragment = OverViewFragment.getInstance(FileExploreActivity.this);
        mPagerAdapter.mFragmentList.add(mCurrentFragment);
        List<String> listStr = new ArrayList<String>();
        listStr.add(getString(R.string.title_section_overview));
        
        //init storageStatus
        StorageStatus ss = new StorageStatus();
        ss.path = StorageUtil.getInternalStorage().getAbsolutePath();
        ss.available = StorageUtil.getInternalStorageState();
        ss.title = getString(R.string.title_section_internal);
        mStorageStatus.put(DetailedListFragment.FRAGMENT_TYPE_INTERNAL, ss);
        ss = new StorageStatus();
        ss.path = StorageUtil.getExternalStorage().getAbsolutePath();
        ss.available = StorageUtil.getExternalStorageState();
        ss.title = getString(R.string.title_section_external);
        mStorageStatus.put(DetailedListFragment.FRAGMENT_TYPE_EXTERNAL, ss);
        ss = new StorageStatus();
        ss.path = StorageUtil.getUSBStorage().getAbsolutePath();
        ss.available = StorageUtil.getUSBStorageState();
        ss.title = "USB DISK";
        mStorageStatus.put(DetailedListFragment.FRAGMENT_TYPE_USB, ss);
        int count = 0;
        for(int i = 0; i < STORAGE_SYZE; i++) {
            ss = mStorageStatus.valueAt(i);
            if(ss.available) {
                listStr.add(ss.title);
                mPagerAdapter.mFragmentList.add(DetailedListFragment.init(this, mStorageStatus.keyAt(i)));
                ss.tabIndex = ++count;
            }
        }
        mNavigationAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, listStr);
        mNavigationAdapter.setDropDownViewResource(R.layout.activities_spinner_dropdown_item);
        mActionBar = getActionBar();
        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        mActionBar.setListNavigationCallbacks(mNavigationAdapter, new ActionBar.OnNavigationListener() {

            @Override
            public boolean onNavigationItemSelected(int itemPosition, long itemId) {
                if (FileExploreActivity.this.mViewPager.getCurrentItem() != mActionBar.getSelectedNavigationIndex())
                    mViewPager.setCurrentItem(itemPosition);
                return true;
            }
        });
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mPagerAdapter);
        mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
            private int prePos = 0;
            @Override
            public void onPageScrollStateChanged(int arg0) {}

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {}

            @Override
            public void onPageSelected(int position) {
                Log.i(TAG, "onPageSelected position is "+ position);
                mActionBar.setSelectedNavigationItem(position);
                mCurrentFragment = mPagerAdapter.getItem(position);
                mActionBar.setIcon(mCurrentFragment.getIcon());
                StorageStatus ss = getStorageStatusByPosition(position);
                if(ss != null) {
                    ss.idHidden = false;
                }
                ss = getStorageStatusByPosition(prePos);
                if(ss != null) {
                    ss.idHidden = true;
                }
                prePos = position;
            }
        });
	}
	
	
	@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        String pastePath = intent.getStringExtra(FilePasteActivity.PASTE_DEST_PATH);
        if(pastePath == null)
            return;
        int index = 0;
        StorageStatus ss;
        for(; index < STORAGE_SYZE; index++) {
            ss = mStorageStatus.valueAt(index);
            if(pastePath.startsWith(ss.path)) {
                break;
            }
        }
        if(index == STORAGE_SYZE) {
            return;
        }
        ss = mStorageStatus.valueAt(index);
        int changeToItem = ss.tabIndex;
        if(mViewPager.getCurrentItem() != changeToItem) {
            mViewPager.setCurrentItem(changeToItem);
        }
        FileListAdapter adapter = (FileListAdapter) mCurrentFragment.getAdapter();
        File pasteResultFile = new File(pastePath);
        if(adapter != null) {
            adapter.setCurrentPath(pasteResultFile);
        } else {
            DetailedListFragment tmp = (DetailedListFragment) mCurrentFragment;
            tmp.setTopPath(pasteResultFile);
        }
    }

    /**
	 * The {@link StorageReceiver} that receive SDCard mounting action, and call
	 * this back. TODO:We should add our protection and UI changing here, like
	 * cancel copy and paste and others.
	 */
	private void onStorageChanged(String path, boolean available) {
	    int index = 0;
	    for(; index < STORAGE_SYZE; index++) {
	        if(path.startsWith(mStorageStatus.valueAt(index).path)) {
	            break;
	        }
	    }
	    if(index >= STORAGE_SYZE) {
	        return;
	    }
	    StorageStatus ss = mStorageStatus.valueAt(index);
	    if(ss.available == available) {
	        //not change, do nothing
	        return;
	    }
	    ss.available = available;
	    FileListAdapter needRefreshFla = null;
	    if(available) {
	        DetailedListFragment fragment = DetailedListFragment.init(this, mStorageStatus.keyAt(index));
	        needRefreshFla = fragment.getAdapter();
	        mPagerAdapter.mFragmentList.add(fragment);
	        mNavigationAdapter.add(ss.title);
	        ss.tabIndex = mPagerAdapter.mFragmentList.size();
	    } else {
	        mPagerAdapter.mFragmentList.remove(DetailedListFragment.getInstance(mStorageStatus.keyAt(index)));
	        mNavigationAdapter.remove(ss.title);
	        ss.tabIndex = -1;
	        for(index++; index < STORAGE_SYZE; index++) {
	            ss = mStorageStatus.valueAt(index);
	            if(ss.tabIndex != -1) {
	                ss.tabIndex--;
	            }
	        }
	    }
	    mPagerAdapter.notifyDataSetChanged();
	    if(needRefreshFla != null) {
	        needRefreshFla.refresh();
	    }
		invalidateOptionsMenu();
	}

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        Log.d(TAG, "onPrepareOptionsMenu");
        if(menu != null){
            menu.clear();
        }
        if(StorageUtil.getInternalStorageState() || StorageUtil.getExternalStorageState()){
            getMenuInflater().inflate(R.menu.main, menu);
        }
        return true;
    }
    
	/**
	 * We use this to manage our fragments. A {@link FragmentPagerAdapter} that
	 * returns a fragment corresponding to one of the sections/tabs/pages.
	 */
	public class SectionsPagerAdapter extends FragmentPagerAdapter {
	    
		ArrayList<BaseFragment> mFragmentList = new ArrayList<BaseFragment>();
		
		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public BaseFragment getItem(int position) {
			return mFragmentList.get(position);
		}

		/**
		 * Override this method to set the title of ActionBar
		 * 
		 * @Override {@link FragmentPagerAdapter#setPrimaryItem(ViewGroup, int, Object)}
		 */
		public void setPrimaryItem(ViewGroup container, int position,
				Object object) {
			if (object != null)
			    super.setPrimaryItem(container, position, object);
			else 
			    Log.d(TAG, "setPrimaryItem failed, container: " + container
			        + ", object: " + object);
		}

		@Override
		public int getCount() {
			return mFragmentList.size();
		}

		@Override
		public CharSequence getPageTitle(int position) {
		    StorageStatus ss = getStorageStatusByPosition(position);
		    if(ss == null) {
		        return getText(R.string.title_section_overview);
		    } else {
		        return ss.title;
		    }
		}
	}
	
	@Override
	protected void onDestroy() {
		Log.d(TAG, "onDestroy");
		StorageUtil.removeStorageChangeListener(mStorageChangedListener);
		super.onDestroy();
		DetailedListFragment.clearFragment();
	}

	@Override
	public void finish() {
		moveTaskToBack(true);
	}

	/**
	 * When back key pressed, we call every {@link BaseFragment#onBackPressed}
	 * in current displaying fragment
	 */
	public void onBackPressed() {
		processBackKey();
	}

    private void processBackKey() {
        if (mCurrentFragment.onBackPressed()) {
            moveTaskToBack(false);
        }
    }

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			processBackKey();
			return true;
		case R.id.action_settings:
			Intent intent = new Intent(this, SettingActivity.class);
			startActivity(intent);
			return true;
        case R.id.searchfile:
            this.startActivity(new Intent().setClass(
                    this.getApplicationContext(), FileSearchActivity.class));
            return true;
		}
		return super.onOptionsItemSelected(item);
	}

    @Override
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mCurrentFragment instanceof DetailedListFragment) {
                FileListAdapter adapter = (FileListAdapter) mCurrentFragment.getAdapter();
                if (adapter != null) {
                    adapter.setCurrentPath(adapter.getTopPath());
                    return true;
                }
            }
        }
        return super.onKeyLongPress(keyCode, event);
    }
    
    static class StorageStatus {
        String title;
        String path;
        boolean available = false;
        boolean idHidden = true;
        int tabIndex = -1;
        @Override
        public String toString() {
            return "StorageStatus [title=" + title + ", path=" + path + ", available=" + available
                    + ", idHidden=" + idHidden + ", tabIndex=" + tabIndex + "]";
        }
    }
    
    private StorageStatus getStorageStatusByPosition(int position) {
        if(position <= 0) {
            return null;
        }
        for(int index = 0; index < STORAGE_SYZE; index++) {
            if(mStorageStatus.valueAt(index).tabIndex == position) {
                return mStorageStatus.valueAt(index);
            }
        }
        return null;
    }
}
